<?php
/**
 * JoiGallery - image gallery component for Joostina
 *
 * Core Classes
 *
 * @version 1.0 alpha 3
 * @package JoiGallery
 * @filename joigallery.class.php
 * @author JoostinaTeam
 * @copyright (C) 2008-2009 Joostina Team
 * @license see license.txt
 *
 **/

// запрет прямого доступа
defined('_VALID_MOS') or die();

$mainframe->addLib('dbconfig');

define("_JOI_GALLERY_FRONT", $mainframe->getCfg('absolute_path') . '/administrator/components/com_joivideo');
define('_JOI_GALLERY_ADMIN', $mainframe->getCfg('absolute_path') . DS . 'administrator' . DS . 'components' . DS . 'com_joivideo');

require_once ($mainframe->getCfg('absolute_path') . '/components/com_joivideo/lib/image.class.php');
if (!defined('JOIRIGHTS')) {
    require_once ($mainframe->getCfg('absolute_path') . '/components/com_joivideo/lib/joiRights.class.php');
}
if (!defined('JOIEXTRAFIELDS')) {
    require_once ($mainframe->getCfg('absolute_path') . '/components/com_joivideo/lib/joiExtraFields.class.php');
}
if (!defined('JOITEMPLATES')) {
    require_once ($mainframe->getCfg('absolute_path') . '/components/com_joivideo/lib/joiTemplates.class.php');
}
if (!defined('JOIPLUGINS')) {
    require_once ($mainframe->getCfg('absolute_path') . '/components/com_joivideo/lib/joiPlugins.class.php');
}
if (!defined('JOITAGS') && is_file($joitags_file = $mainframe->getCfg('absolute_path') . '/components/com_joitags/joitags.class.php')) {
    require_once ($joitags_file);
}

if (file_exists($lang_file = $mainframe->getCfg('absolute_path') . '/components/com_joivideo/language/' . $mainframe->getCfg('lang') . '.php')) {
    require_once ($lang_file);
}
else {
    require_once ($mainframe->getCfg('absolute_path') . '/components/com_joivideo/language/english.php');
}

class joiGalleryVideo extends mosDBTable {

    /** @var int **/
    var $id = null;
    /** @var int **/
    var $cid = null;
    /** @var string **/
    var $name = null;
    /** @var int **/
    var $user_id = null;
    /** @var datetime */
    var $created = null;
    /** @var text description **/
    var $description = null;
    /**
     @var string path **/
    var $path = null;
    /**
     @var boolean default **/
    var $default = null;
    /**
     @var int ordering **/
    var $ordering = null;
    /**
     @var tinyint state **/
    var $state = null;
    
    function joiGalleryVideo(& $db) {
	$this->mosDBTable('#__joivideo', 'id', $db);
    }
    
    function clean_default($cid) {

	$query = 'UPDATE #__joivideo SET `default` = 0 WHERE cid = ' . (int) $cid;
	$this->_db->setQuery($query);
	return $this->_db->query();
    }
    
    function get_img_atribs($row, $config) {
	$mainframe = & mosMainFrame::getInstance();

	$curr = @getimagesize($mainframe->getCfg('absolute_path') . $config->original_path . '/' . $row->path);
	$row->width = $curr[0];
	$row->height = $curr[1];
	$row->size = round(filesize($mainframe->getCfg('absolute_path') . $config->original_path . '/' . $row->path) / 1024);

	return $row;
    }
    
    function get_next($row, $params, $count = 2) {

	$and = 'ordering > ' . $row->ordering;
	if ($params->images_sort !== 'ordering') {
	    $and = 'id > ' . $row->id;
	}

	$order = $params->images_sort;
	if ($params->images_sort == 'id DESC') {
	    $order = 'id ASC ';
	}

	$query = 'SELECT id, ordering,  description, path FROM #__joivideo
      	WHERE cid = ' . (int) $row->cid . ' AND state = 1  AND ' . $and . '
      	ORDER BY ' . $order . ' LIMIT ' . $count;

	$this->_db->setQuery($query);
	return $this->_db->loadObjectList();
    }
    
    function get_prev($row, $params, $count = 2) {

	$and = 'ordering < ' . $row->ordering;
	if ($params->images_sort !== 'ordering') {
	    $and = 'id < ' . $row->id;
	}

	$query = 'SELECT id, ordering,  description, path FROM #__joivideo
      	WHERE cid = ' . (int) $row->cid . ' AND state = 1  AND ' . $and . '
      	ORDER BY ' . $params->images_sort . ' LIMIT ' . $count;

	$this->_db->setQuery($query);
	return $this->_db->loadObjectList();
    }
    
    function get_count_photos($cid, $params = null, $subcats = null) {
	global $my;

	$cid = (int) $cid;
	if ($subcats) {
	    foreach ($subcats as $subcat) {
		$cid .= ' OR cid = ' . (int) $subcat->id;
	    }
	}

	$query = 'SELECT COUNT(*) FROM #__joigallery
		WHERE cid = ' . $cid . ' ';

	if ($my->gid != 2) {
	    $query .= 'AND state = 1 ';
	}

	$query .= 'ORDER BY ordering';

	$this->_db->setQuery($query);
	return $this->_db->loadResult();
    }
    
    function load_photos($cid, $params = null, $subcats = null) {
	global $my;

	$cid = (int) $cid;
	if ($subcats) {
	    foreach ($subcats as $subcat) {
		$cid .= ' OR cid = ' . (int) $subcat->id;
	    }
	}

	$query = 'SELECT * FROM #__joigallery
		WHERE cid = ' . $cid . ' ';

	if ($my->gid != 2) {
	    $query .= 'AND state = 1 ';
	}

	$query .= 'ORDER BY ' . $params->images_sort;

	$this->_db->setQuery($query, $params->_limitstart, $params->_limit);
	return $this->_db->loadObjectList();
    }
    
    function get_count_photos_with_subcats($cid) {
	global $my;

	$query = 'SELECT COUNT(*) FROM #__joigallery
		WHERE cid = ' . (int) $cid . ' ';

	if ($my->gid != 2) {
	    $query .= 'AND state = 1 ';
	}

	$query .= 'ORDER BY ordering';

	$this->_db->setQuery($query);
	return $this->_db->loadResult();
    }
    
    function load_photos_with_subcats($cid, $params) {
	global $my;

	$query = 'SELECT * FROM #__joigallery
		WHERE cid = ' . (int) $cid . ' ';

	if ($my->gid != 2) {
	    $query .= 'AND state = 1 ';
	}

	$query .= 'ORDER BY ' . $params->images_sort;

	$this->_db->setQuery($query, $params->_limitstart, $params->_limit);
	return $this->_db->loadObjectList();
    }
    
    function get_count_photos_admin($cid) {

	$where = array();
	if ($cid > 0) {
	    $where[] = 'g.cid = ' . $cid;
	}

	$query = "SELECT COUNT(1) FROM #__joigallery g LEFT JOIN #__categories c ON g.cid = c.id ";
	if (sizeof($where) > 0) {
	    $query .= "WHERE " . implode(" AND ", $where);
	}
	$query .= " ORDER BY cid, g.ordering";

	$this->_db->setQuery($query);
	return $this->_db->loadResult();
    }
    
    function load_photos_admin($cid, $limitstart, $limit) {

	$where = array();
	if ($cid > 0) {
	    $where[] = 'g.cid = ' . $cid;
	}

	$query = "SELECT g.*, c.name AS category FROM #__joigallery g LEFT JOIN #__categories c ON g.cid = c.id ";
	if (sizeof($where) > 0) {
	    $query .= "WHERE " . implode(" AND ", $where);
	}
	$query .= " ORDER BY cid, g.ordering";

	$this->_db->setQuery($query, $limitstart, $limit);
	return $this->_db->loadObjectList();
    }
    
    function check_photos_by_cat($cid) {

	$query = "SELECT COUNT(1) FROM #__joigallery WHERE cid = " . (int) $cid;
	$this->_db->setQuery($query);
	return $this->_db->loadResult();
    }
    
    function check_subcats_by_cat($cid) {

	$query = "SELECT COUNT(1) FROM #__categories WHERE parent_id = $cid";
	$this->_db->setQuery($query);
	return $this->_db->loadResult();
    }
    
    function remove_images($row, $config) {
	$mainframe = & mosMainFrame::getInstance();

	$a_path = $mainframe->getCfg('absolute_path');
	$dirs = array($config->image_path, $config->thumbnail_path, $config->original_path);

	foreach ($dirs as $dir) {
	    $img = $a_path . $dir . DS . $row->path;
	    unlink($img);
	    //if (!unlink($img)) {
	    //return joiGalleryError::error('Failed to remove image: ' . $img);
	    //}

	}
    }
    
    function check_main_photo($cat) {

	$query = "SELECT COUNT(id) FROM #__joigallery WHERE default = 1 AND cid = " . $cat;
	$this->_db->setQuery($query);
	if (!$this->_db->loadResult()) {
	    $query = "SELECT MAX(id) FROM #__joigallery WHERE state = 1 AND cid = " . $cat;
	    $this->_db->setQuery($query);
	    $max = $this->_db->loadResult();

	    $query = 'UPDATE #__joigallery SET `default` = 1 WHERE id = ' . $max;
	    $this->_db->setQuery($query);
	    return $this->_db->query();
	}
    }
}

class joiGalleryRights extends joiRights {
    
    var $view_cat = null;
    var $view_unpub_cat = null;
    var $view_photo = null;
    var $view_unpub_photo = null;
    var $add_photo_single = null;
    var $add_photo_archive = null;
    var $edit_photo = null;
    var $edit_own_photo = null;
    var $del_photo = null;
    var $del_own_photo = null;
    var $add_cat = null;
    var $edit_cat = null;
    var $edit_own_cat = null;
    var $del_cat = null;
    var $del_own_cat = null;
    var $no_premoderate = null;
    var $set_state = null;
    var $set_state_own = null;
    var $main_photo = null;
    var $main_photo_own = null;
    
    function joiGalleryRights($config_rights) {

	$rights_label = array(
	    'view_cat' => 'Просмотр категории',
	    'view_unpub_cat' => 'Просмотр неопубликованной категории',
	    'view_photo' => 'Просмотр страницы фото',
	    'view_unpub_photo' => 'Просмотр неопубликованных фото',
	    'add_photo_single' => 'Загрузка фото',
	    'add_photo_archive' => 'Загрузка архивом',
	    'edit_photo' => 'Редактирование любого фото',
	    'edit_own_photo' => 'Редактирование своих фото',
	    'del_photo' => 'Удаление любого фото',
	    'del_own_photo' => 'Удаление своих фото',
	    'add_cat' => 'Добавление категорий',
	    'edit_cat' => 'Редактирование любой категории',
	    'edit_own_cat' => 'Редактирование своих категорий',
	    'del_cat' => 'Удаление любой категории',
	    'del_own_cat' => 'Удаление своей категории',
	    'no_premoderate' => 'Публикация без премодерации',
	    'set_state' => 'Смена статуса любой публикации',
	    'set_state_own' => 'Смена статуса своей публикации',
	    'main_photo' => 'Назначение главного фото в любой категории',
	    'main_photo_own' => 'Назначение главного фото в своей категории'
	);

	$error_messages = array(
	    'view_cat' => 'Извините, Вы не можете просматривать эту категорию',
	    'view_unpub_cat' => 'Категория не существует или не опубликована',
	    'view_photo' => 'Извините, у Вас нет доступа к этому изображению',
	    'view_unpub_photo' => 'Изображение не существует или не опубликовано',
	    'add_photo_single' => 'Извините, Вы не можете загружать фото',
	    'add_photo_archive' => 'Извините, Вы не можете загружать фото',
	    'edit_photo' => 'Извините, у Вас нет доступа к редактированию фото',
	    'edit_own_photo' => 'Извините, у Вас нет доступа к редактированию фото',
	    'del_photo' => 'Извините, Вы не можете удалять изображения',
	    'del_own_photo' => 'Извините, Вы не можете удалять изображения',
	    'add_cat' => 'Извините, Вы не можете добавлять категории',
	    'edit_cat' => 'Извините, Вы не можете редактировать категории',
	    'edit_own_cat' => 'Извините, Вы не можете редактировать категории',
	    'del_cat' => 'Извините, Вы не можете удалять категории',
	    'del_own_cat' => 'Извините, Вы не можете удалять категории',
	    'no_premoderate' => 'Изображение будет опубликовано после проверки модератором',
	    'set_state' => '',
	    'set_state_own' => '',
	    'main_photo' => '',
	    'main_photo_own' => ''
	);

	$this->joiRights($config_rights, $rights_label, $error_messages);
	return true;
    }
}

class joiGalleryConfig extends dbConfig {

    var $original_path = '/images/joigallery';
    var $image_path = '/images/joigallery/resized';
    var $thumbnail_path = '/images/joigallery/thumbs';
    var $max_height = '400';
    var $max_width = '500';
    var $image_crop = 0;
    var $thumbnail_height = '150';
    var $thumbnail_width = '100';
    var $thumb_crop = 0;
    var $allow_formats = "image/pjpeg,image/jpeg,image/jpg,image/png,image/x-png,image/gif";
    var $template_dir = 0;
    var $thumbnails_limit = '10';
    var $template_cat = 'default.php';
    var $template_edit_cat = 'default.php';
    /** Просмотр категории - pathway */
    var $cat_pathway = 1;
    var $images_sort = 'ordering';
    /** Просмотр категории - вывод подкатегорий */
    var $cat_view_subcats = 1;
    /** Просмотр категории - картинки к подкатегориям */
    var $cat_view_subcats_thumb = 1;
    /** Просмотр категории - названия категорий */
    var $cat_name_cat_view = 1;
    /** Просмотр категории - описания категорий */
    var $cat_desc_cat_view = 1;
    /** Просмотр категории - названия изображений */
    var $image_name_cat_view = 1;
    /** Просмотр категории - описания изображений */
    var $image_desc_cat_view = 0;
    /** Просмотр категории - рейтинг изображений */
    var $image_rate_cat_view = 1;
    /** Просмотр изображения - pathway */
    var $image_pathway = 1;
    /** Просмотр изображения - название */
    var $image_name_photo_view = 1;
    /** Просмотр изображения - описание */
    var $image_desc_photo_view = 1;
    var $template_photo = 'default.php';
    var $template_add_photo = 'default.php';
    var $template_edit_photo = 'default.php';
    /** Просмотр изображения - рейтинг изображения */
    var $image_rate_photo_view = 1;
    /** Просмотр изображения - информация */
    var $image_info_photo_view = 1;
    /** Просмотр изображения - автор */
    var $image_author_photo_view = 1;
    /** Просмотр изображения - дата создания */
    var $image_created_photo_view = 1;
    /** Просмотр изображения - навигация по изображениям */
    var $photo_navigation = 1;
    /** Просмотр изображения - лайтбокс */
    var $use_lightbox = 1;
    /** Просмотр изображения - комментарии */
    var $comments = 0;
    /** Просмотр категории - комментарии к фоткам */
    var $comments_cat_view = 0;
    var $add_image_pagetitle = 'Новое фото';
    var $add_image_pubunpub = 1;
    var $add_image_default = 1;
    var $add_image_fname = 1;
    var $add_image_fdesc = 1;
    var $add_image_fdesc_wwyg = 1;
    var $edit_image_cat = 1;
    var $edit_image_pagetitle = 'Редактирование фото';
    var $edit_image_pubunpub = 1;
    var $edit_image_default = 1;
    var $edit_image_fname = 1;
    var $edit_image_fdesc = 1;
    var $edit_image_fdesc_wwyg = 1;
    var $extrafields_add_photo = 0;
    var $extrafields_edit_photo = 0;
    var $extrafields_auto_js = 1;
    var $image_watermark = 0;
    var $thumb_watermark = 0;
    var $original_watermark = 0;
    var $image_watermark_position = 'top_left';
    var $thumb_watermark_position = 'top_left';
    var $original_watermark_position = 'top_left';
    var $u_rights = 'can_view_cat=0,18,19,20,21,23,24,25*can_view_photo=0,18,19,20,21,23,24,25*can_add_photo_single=18,19,20,21,23,24,25*can_add_photo_archive=19,20,21,23,24,25*can_edit_photo=25*can_edit_own_photo=18,19,20,21,23,24,25*can_del_photo=25*can_del_own_photo=18,19,20,21,23,24,25*can_add_cat=25*can_edit_cat=25*can_del_cat=25';
    var $_real_subgroup = null;
    
    function joiGalleryConfig(& $db, $group = 'joigallery', $subgroup = 'default') {

	$this->_real_subgroup = $subgroup;

	$this->dbConfig($db, $group, $this->_real_subgroup);

	if (!$this->_loaded) {
	    $this->dbConfig($db, $group, 'default');
	    $this->_subgroup = $this->_real_subgroup;
	}

	$this->allow_formats = explode(',', $this->allow_formats);
    }
    
    function display_config($option, $isNew = 0) {
	$mainframe = & mosMainFrame::getInstance();

	$list = array();

	if ($isNew) {
	    $categories = joiGalleryCategory::getCategorieTree();

	    $obj = new stdClass();
	    $obj->id = 'default';
	    $obj->name = 'default';
	    array_unshift($categories, $obj);

	    $list['cid'] = mosHTML::selectList($categories, 'group', 'class="inputbox text_area"', 'id', 'name');
	}

	//Сортировка изображений в категории
	$list['images_sort'] = $this->get_sort_list();

	//Позиция водяного знака
	$list['watermak_position'] = $this->get_wmark_list();

	//Системы комментариев
	$list['comment_system'] = $this->get_comment_system_list();

	//Настройка прав пользователей
	$list['u_rights'] = $this->get_u_rights();

	include_once(_JOI_GALLERY_ADMIN . DS . 'view' . DS . 'config.php');
    }
    
    function save_config() {

	$this->allow_formats = implode(',', $this->allow_formats);

	if (!$this->bindConfig($_REQUEST)) {
	    echo "<script> alert('" . $this->_error . "'); window.history.go(-1); </script>";
	    exit();
	}

	$this->u_rights = joiRights::prepare_for_saving($_REQUEST['u_rights']);

	if (!$this->storeConfig()) {
	    echo "<script> alert('" . $this->_error . "'); window.history.go(-1); </script>";
	    exit();
	}
    }
    
    function delete_config($subgroup) {
	$database = & database::getInstance();
	$query = "DELETE FROM #__config  WHERE `group` = 'joigallery' AND `subgroup` = '" . $subgroup . "'";
	$database->setQuery($query);
	$database->query();
    }
    
    function get_configs_list() {

	$database = & database::getInstance();

	$query = 'SELECT a.subgroup FROM #__config AS a WHERE a.group = "joigallery" GROUP BY a.subgroup ';
	$database->setQuery($query);
	return  $database->loadResultArray();
    }
    
    function get_comment_system_list() {
	$mainframe = & mosMainFrame::getInstance();
	$arr = array();

	$arr[0] = mosHTML::makeOption(0, 'Не использовать');

	$jcomments = $mainframe->getCfg('absolute_path') . DS . 'components' . DS . 'com_jcomments' . DS . 'jcomments.class.php';
	$joicomments = $mainframe->getCfg('absolute_path') . DS . 'components' . DS . 'com_joicomments' . DS . 'joicomments.class.php';

	if (is_file($jcomments)) {
	    $arr[] = mosHTML::makeOption('jcomments', 'JComments');
	}

	if (is_file($joicomments)) {
	    $arr[] = mosHTML::makeOption('joicomments', 'JoiComments');
	}

	if (count($arr) > 1) {
	    return mosHTML::selectList($arr, 'comments', 'class="inputbox"', 'value', 'text', $this->comments);
	}
	else {
	    return 'Comments system not found';
	}
    }
    
    function get_sort_list() {
	$arr = array();
	$arr[] = mosHTML::makeOption('ordering', 'Как в админке');
	$arr[] = mosHTML::makeOption('id DESC', 'От новых к старым');
	$arr[] = mosHTML::makeOption('id ASC', 'От старых к новым');
	return mosHTML::selectList($arr, 'images_sort', 'class="inputbox"', 'value', 'text', $this->images_sort);
    }
    
    function get_wmark_list() {
	$arr = array();
	$arr[] = mosHTML::makeOption('top_left', 'Верхний левый угол');
	$arr[] = mosHTML::makeOption('top_right', 'Верхний правый угол');
	$arr[] = mosHTML::makeOption('top_center', 'Сверху по центру');
	$arr[] = mosHTML::makeOption('bottom_left', 'Нижний левый угол');
	$arr[] = mosHTML::makeOption('bottom_right', 'Нижний правый угол');
	$arr[] = mosHTML::makeOption('bottom_center', 'Снизу по центру');
	$arr[] = mosHTML::makeOption('middle', 'В центре изображения');
	return $arr;
    }
    
    function get_u_rights() {

	$u_rights = new joiGalleryRights($this->u_rights);
	$config_table = $u_rights->draw_config_table();
	return $config_table;
    }
}

class joiGalleryHelper {
    
    function _load_core_js() {
	mosMainFrame::getInstance()->addJS(Jconfig::getInstance()->config_live_site . '/components/com_joivideo/js/joigallery.js', 'custom');
    }

    /**
     * Echo pathway
     *
     * @param int current categoryid
     */
    function fixPathway($cid, $photo = null) {
	global $database, $mainframe, $Itemid, $option;

	if ($cid == 0) {
	    return;
	}

	$query = "SELECT * FROM #__categories WHERE section = 'com_joivideo'";
	$database->setQuery($query);
	$cats = $database->loadObjectList('id');

	$pathway = array();
	if (sizeof($cats) > 0) {
	    $cat = $cats[$cid];
	    while ($cat->parent_id != 0) {
		$cat = $cats[$cat->parent_id];
		$pathway[] = '<a href="' . sefRelToAbs('index.php?option=' . $option . '&amp;act=categories&amp;cid=' . $cat->id . '&amp;Itemid=' .
			$Itemid) . '">' . $cat->name . '</a>';
	    }
	}

	$pathway = array_reverse($pathway);
	for ($i = 0, $n = count($pathway); $i < $n; $i++) {
	    $mainframe->appendPathWay($pathway[$i]);
	}
	if (!is_null($photo)) {
	    //photo view, echo linked category
	    $mainframe->appendPathWay('<a href="' . sefRelToAbs('index.php?option=' . $option . '&amp;act=categories&amp;cid=' . $cats[$cid]->id .
			    '&amp;Itemid=' . $Itemid) . '">' . $cats[$cid]->name . '</a>');
	    $mainframe->appendPathWay($photo->name);
	}
	else {
	    if (sizeof($cats) > 0) {
		$mainframe->appendPathWay($cats[$cid]->name);
	    }
	}
    }
    
    function clear_name($name) {

	$name = preg_replace('#\W^\.#is', '', $name);
	$name = Jstring::strtolower($name);
	$name = joiGalleryHelper::translite($name);
	$name = str_replace(' ', '', $name);

	return $name;
    }
    
    function translite($str) {

	static $tbl = array(
    'а'=>'a', 'б'=>'b', 'в'=>'v', 'г'=>'g', 'д'=>'d', 'е'=>'e', 'ж'=>'g', 'з'=>'z',
    'и'=>'i', 'й'=>'y', 'к'=>'k', 'л'=>'l', 'м'=>'m', 'н'=>'n', 'о'=>'o', 'п'=>'p',
    'р'=>'r', 'с'=>'s', 'т'=>'t', 'у'=>'u', 'ф'=>'f', 'ы'=>'i', 'э'=>'e', 'А'=>'A',
    'Б'=>'B', 'В'=>'V', 'Г'=>'G', 'Д'=>'D', 'Е'=>'E', 'Ж'=>'G', 'З'=>'Z', 'И'=>'I',
    'Й'=>'Y', 'К'=>'K', 'Л'=>'L', 'М'=>'M', 'Н'=>'N', 'О'=>'O', 'П'=>'P', 'Р'=>'R',
    'С'=>'S', 'Т'=>'T', 'У'=>'U', 'Ф'=>'F', 'Ы'=>'I', 'Э'=>'E', 'ё'=>"yo", 'х'=>"h",
    'ц'=>"ts", 'ч'=>"ch", 'ш'=>"sh", 'щ'=>"shch", 'ъ'=>"", 'ь'=>"", 'ю'=>"yu", 'я'=>"ya",
    'Ё'=>"YO", 'Х'=>"H", 'Ц'=>"TS", 'Ч'=>"CH", 'Ш'=>"SH", 'Щ'=>"SHCH", 'Ъ'=>"", 'Ь'=>"",
    'Ю'=>"YU", 'Я'=>"YA"
	);

	return strtr($str, $tbl);
    }
    
    function get_cat_link($cid, $params) {
	$link = sefRelToAbs('index.php?option=' . $params->_option . '&amp;act=categories&amp;cid=' . $cid . '&amp;Itemid=' . $params->_Itemid);
	return $link;
    }
    
    function get_thumb($photo_path, $config, $mainframe) {

	$img = $mainframe->getCfg('live_site') . $config->thumbnail_path . '/' . $photo_path;
	$img_file = $mainframe->getCfg('absolute_path') . $config->thumbnail_path . '/' . $photo_path;
	if (!is_file($img_file)) {
	    $img = $mainframe->getCfg('live_site') . '/images/noimage.jpg';
	}

	return $img;
    }
    
    function get_my_gid() {
	global $my;

	if ($my->id) {
	    $database = & database::getInstance();

	    $query = "SELECT gid FROM #__users WHERE id = " . (int) $my->id;
	    $database->setQuery($query);
	    return $database->loadResult();
	}
	else {
	    return 0;
	}
    }
}

class processImage {
    
    function upload_handler($params) {
	$database = & database::getInstance();

	$group = mosGetParam($_REQUEST, 'cid', 'default');
	//$config = new joiGalleryConfig($database, 'joigallery', $group);

	$config = $params;

	//Загрузка одиночного изображения
	if (!empty($_FILES['photo']['name'])) {
	    return self::upload_single($config);
	}
	//Загрузка zip-архива
	elseif (!empty($_FILES['zip']['name'])) {
	    return self::upload_zip_archive($config);
	}
	//Загрузка из директории
	else {
	    return self::upload_directory($config);
	}
    }
    
    function upload_single($config) {

	global $option, $database, $mainframe;

	$uploader = new joiGalleryUploader('upload_single', $config->allow_formats);
	if (!$uploader->process_upload()) {
	    joiGalleryError::error($uploader->error);
	}

	$_file = new StdClass();
	$_file->filepath = $_FILES['photo']['tmp_name'];
	$_file->filename = $_FILES['photo']['name'];
	$_file->imagename = mosGetParam($_REQUEST, 'name', '');
	$_file->filetype = $_FILES['photo']['type'];
	$_file->description = mosGetParam($_REQUEST, 'description', '', _MOS_ALLOWHTML);
	$_file->cid = mosGetParam($_REQUEST, 'cid', 0);
	$_file->state = mosGetParam($_REQUEST, 'state', 0);


	self::addFile($_file, $config);

	return 1;
    }
    
    function upload_zip_archive($config) {

	global $option, $database, $mainframe;

	$uploader = new joiGalleryUploader('upload_zip_archive', $config->allow_formats);
	if (!$uploader->process_upload()) {
	    joiGalleryError::error($uploader->error);
	}

	$_file = new StdClass();
	$_file->imagename = mosGetParam($_REQUEST, 'name', '');
	$_file->description = mosGetParam($_REQUEST, 'description', '', _MOS_ALLOWHTML);
	$_file->cid = mosGetParam($_REQUEST, 'cid', 0);
	$_file->state = mosGetParam($_REQUEST, 'state', 0);
	$_file->sort = mosGetParam($_REQUEST, 'sort', 'name');

	$files = mosReadDirectory($uploader->tmpdir, '.', false, true);
	self::sortFiles($files, $_file->sort);

	if (sizeof($files) == 0) {
	    joiGalleryError::error("No files found in extracted archive");
	}

	$added_files = 0;
	for ($i = 0, $n = count($files); $i < $n; $i++) {

	    $_file->filepath = str_replace("\\", '/', $files[$i]);

	    if (!is_file($_file->filepath)) {
		continue;
	    }

	    $name = explode("/", $_file->filepath);
	    $_file->filename = $name[sizeof($name) - 1];

	    $res = getimagesize($_file->filepath);
	    $_file->filetype = $res['mime'];

	    if (in_array($_file->filetype, $config->allow_formats)) {
		self::addFile($_file, $config);
		$added_files++;
	    }

	    unlink($_file->filepath);
	}

	rmdir($uploader->tmpdir);

	//Возвращаем количество добавленных файлов
	return $added_files;
    }
    
    function upload_directory($config) {
	global $option, $database, $mainframe;

	$dir = mosGetParam($_REQUEST, 'dir', '');

	$uploader = new joiGalleryUploader('upload_directory', $config->allow_formats);
	if (!$uploader->process_upload($dir)) {
	    joiGalleryError::error($uploader->error);
	}

	$_file = new StdClass();
	$_file->imagename = mosGetParam($_REQUEST, 'name', '');
	$_file->description = mosGetParam($_REQUEST, 'description', '', _MOS_ALLOWHTML);
	$_file->cid = mosGetParam($_REQUEST, 'cid', 0);
	$_file->state = mosGetParam($_REQUEST, 'state', 0);
	$_file->sort = mosGetParam($_REQUEST, 'sort', 'name');


	$files = mosReadDirectory($dir, '.', false, true);
	self::sortFiles($files, $_file->sort);

	if (sizeof($files) == 0) {
	    joiGalleryError::error("No files were found in $dir");
	}

	$added_files = 0;
	for ($i = 0, $n = count($files); $i < $n; $i++) {


	    $_file->filepath = str_replace("\\", '/', $files[$i]);

	    if (!is_file($_file->filepath)) {
		continue;
	    }

	    $name = explode("/", $_file->filepath);
	    $_file->filename = $name[sizeof($name) - 1];

	    copy($_file->filepath, $uploader->tmpdir . '/' . $_file->filename);

	    $res = getimagesize($uploader->tmpdir . '/' . $_file->filename);
	    $_file->filetype = $res['mime'];

	    $_file->filepath = $uploader->tmpdir . '/' . $_file->filename;

	    if (in_array($_file->filetype, $config->allow_formats)) {
		self::addFile($_file, $config);
		$added_files++;
	    }

	    unlink($_file->filepath);
	}

	rmdir($uploader->tmpdir);

	//Возвращаем количество добавленных файлов
	return $added_files;
    }

    /**
     * Перемещение фото в директорию назначения,
     * создание эскизов, сохранение записи в БД
     */
    function addFile($_file, $config) {
	global $database, $mainframe;

	//Очищаем название файла от всяких ненужностей
	$_file->filename = joiGalleryHelper::clear_name($_file->filename);

	//Проверяем права на запись директории галереи
	if (!is_writable($mainframe->getCfg('absolute_path') . '/' . $config->original_path)) {
	    joiGalleryError::error('Directory not writable: ' . $mainframe->getCfg('absolute_path') . '/' . $config->original_path);
	}

	$img_title = '';
	if (!empty($_file->imagename)) {
	    $img_title = $_file->imagename;
	}
	else {
	    $n = explode('.', $_file->filename);
	    $img_title = $n[0];
	}

	//Грузим оригинальное изображение
	$file_options = array(
	    'temp_path' => $_file->filepath,
	    'target_dir_original' => $mainframe->getCfg('absolute_path') . $config->original_path . '/' . $_file->cid,
	    'target_dir_middle' => $mainframe->getCfg('absolute_path') . $config->image_path . '/' . $_file->cid,
	    'target_dir_thumbs' => $mainframe->getCfg('absolute_path') . $config->thumbnail_path . '/' . $_file->cid,
	    'file_prefix' => time(),
	    'filename' => $_file->filename,
	    'name' => $img_title,
	    'ordering' => '99999',
	    'description' => $_file->description,
	    'cid' => $_file->cid,
	    'state' => $_file->state
	);
	$img_original = new joiGalleryImage($file_options);

	if (!$img_original->upload()) {
	    joiGalleryError::error($img_original->error);
	}
	//Водяной знак
	if ($config->original_watermark) {
	    $stamp = new water($file_options['target_dir_original'] . DS . $file_options['file_prefix'] . '_' . $file_options['filename'],
		    'images/watermark/big.png', $config->original_watermark_position);
	    $stamp->stampPicture();
	}


	//Создаем средний эскиз изображения
	$options_middle = array(
	    'method' => $config->image_crop,
	    'output_file' => '',
	    'width'  => $config->max_width,
	    'height' => $config->max_height
	);
	if (!$img_original->create_middle($options_middle)) {
	    joiGalleryError::error($img_original->error);
	}
	//Водяной знак
	if ($config->image_watermark) {
	    $stamp = new water($file_options['target_dir_middle'] . DS . $file_options['file_prefix'] . '_' . $file_options['filename'],
		    'images/watermark/middle.png', $config->image_watermark_position);
	    $stamp->stampPicture();
	}

	//Создаем превью изображения
	$options_thumb = array(
	    'method' => $config->thumb_crop, //0 - сохранять пропорции, 1 - точная обрезка, 2 - только обрезка, без изменения размеров
	    'output_file' => '',
	    'width'  => $config->thumbnail_width,
	    'height' => $config->thumbnail_height
	);
	if (!$img_original->create_thumb($options_thumb)) {
	    joiGalleryError::error($img_original->error);
	}
	//Водяной знак
	if ($config->thumb_watermark) {
	    $stamp = new water($file_options['target_dir_thumbs'] . DS . $file_options['file_prefix'] . '_' . $file_options['filename'],
		    'images/watermark/small.png', $config->thumb_watermark_position);
	    $stamp->stampPicture();
	}

	//Сохраняем запись в БД
	self::store_photo($file_options, $config);
    }

    /**
     * сохранение новой записи в БД
     */
    function store_photo($file_options = array(), $config) {
	global $my;

	$database = & database::getInstance();
	$mainframe = & mosMainFrame::getInstance();

	$row = new joiGalleryPhoto($database);

	$fields_row = get_object_vars($row);
	foreach ($fields_row as $key=>$v) {
	    if (isset($file_options[$key])) {
		$row->$key = $file_options[$key];
	    }
	}

	$row->path = $row->cid . '/' . $file_options['file_prefix'] . "_" . $file_options['filename'];
	$row->user_id = $my->id;
	$row->created = date('Y-m-d H:i:s');

	if (self::check_first_photo($row->cid) == 0) {
	    $row->default = 1;
	}


	if (!$config->get('add_image_pubunpub', 1) || (
		!$config->_access->allow_me('set_state', $my->_gid) || !$config->_access->allow_me('set_state_own', $my->_gid)
	)) {
	    if ($config->_access->allow_me('no_premoderate', $my->_gid)) {
		$row->state = 1;
	    }
	    else {
		$row->state = 0;
	    }
	}


	if (!$row->check()) {
	    echo "<script> alert('" . $row->getError() . "'); window.history.go(-1); </script>\n";
	    exit();
	}
	if (!$row->store()) {
	    echo "<script> alert('" . $row->getError() . "'); window.history.go(-1); </script>\n";
	    exit();
	}

	$row->updateOrder('cid = ' . (int) $row->cid);

	//Дополнительные поля
	$extra_fields = new joiExtraFields($mainframe, 'com_joivideo');
	$extra_fields->save_fields_values($row->id);
    }

    /** check if first image from this gallery **/
    function check_first_photo($cid) {
	$database = & database::getInstance();

	$query = 'SELECT COUNT(1) FROM #__joigallery WHERE cid = ' . (int) $cid;
	$database->setQuery($query);

	return $database->loadResult();
    }
    
    function sortFiles(& $array, $sort = 'name') {
	if ($sort == 'name') { //sort by name
	    sort($array);
	}
	else
	if ($sort == 'rname') { //sort by name - reversed
	    rsort($array);
	}
	else
	if ($sort == 'c_date') { //sort by date created
	    $new_array = array();
	    for ($i = 0, $n = count($array); $i < $n; $i++) {
		$file = $array[$i];
		$new_array[filectime($file)] = $file;
	    }
	    ksort($new_array);
	    $array = & array_values($new_array);
	}
	else
	if ($sort == 'm_date') { //sort by date modified
	    $new_array = array();
	    for ($i = 0, $n = count($array); $i < $n; $i++) {
		$file = $array[$i];
		$new_array[filemtime($file)] = $file;
	    }
	    ksort($new_array);
	    $array = & array_values($new_array);
	}
    }
}

class joiGalleryCategory  extends mosCategory {
    
    function get_categories($cid) {
	global $my;

	$query = 'SELECT c.*, e.path AS photo_path, e.state, e.name AS photo_name
		FROM #__categories AS c
		LEFT JOIN #__joigallery AS e ON c.id = e.cid AND e.state = 1 AND e.default = 1
		WHERE c.section = \'com_joivideo\' 
		AND c.parent_id = ' . (int) $cid . ' ';

	if ($my->gid != 2) {
	    $query .= 'AND c.published = 1 ';
	}

	$query .= 'GROUP BY c.id ORDER BY c.ordering';

	$this->_db->setQuery($query);
	return $this->_db->loadObjectList();
    }
    
    function get_categories_count_admin($cid = 0, $search = '') {

	$where = array();
	$where[] = "section = 'com_joivideo'";

	if (!empty($search)) {
	    $where[] = "c.title LIKE '%" . $search . "%'";
	}

	if ($cid > 0) {
	    $where[] = 'c.parent_id = ' . $cid;
	}

	$query = "SELECT COUNT(1) FROM #__categories c ";
	if (sizeof($where) > 0) {
	    $query .= "WHERE " . implode(" AND ", $where);
	}
	$query .= " ORDER BY parent_id, ordering";

	$this->_db->setQuery($query);
	return $this->_db->loadResult();
    }
    
    function get_categories_admin($cid) {

	$where = array();
	$where[] = "section = 'com_joivideo'";

	if (!empty($search)) {
	    $where[] = "c.title LIKE '%" . $search . "%'";
	}

	if ($cid > 0) {
	    $where[] = 'c.parent_id = ' . $cid;
	}

	$query = "SELECT * FROM #__categories c ";
	if (sizeof($where) > 0) {
	    $query .= "WHERE " . implode(" AND ", $where);
	}
	$query .= " ORDER BY parent_id, ordering";

	$this->_db->setQuery($query);
	return $this->_db->loadObjectList();
    }
    
    function generate_tree($cats) {

	$children = array();
	foreach ($cats as $v) {
	    $pt = $v->parent_id;
	    $list = @$children[$pt] ? $children[$pt] : array();
	    array_push($list, $v);
	    $children[$pt] = $list;
	}
	$list = self::TreeRecurse(0, '', array(), $children);
	return $list;
    }
    
    function TreeRecurse($id, $indent, $list,  $children, $maxlevel = 9999, $level = 0, $type = 1) {

	if (@$children[$id] && $level < $maxlevel) {
	    foreach ($children[$id] as $v) {
		$id = $v->id;

		if ($type) {
		    $pre = '<sup>L</sup>&nbsp;';
		    $spacer = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
		} else {
		    $pre = '- ';
		    $spacer = '&nbsp;&nbsp;';
		}

		if ($v->parent_id == 0) {
		    $txt = $v->title;
		} else {
		    $txt = $pre . $v->title;
		}

		$list[$id] = $v;
		$list[$id]->treename = $indent . $txt;
		$list[$id]->children = count(@$children[$id]);

		$list = self::TreeRecurse($id, $indent . $spacer, $list, $children, $maxlevel, $level + 1, $type);
	    }
	}
	return $list;
    }
    
    function getCategorieTree($published_only = false) {
	global $mainframe, $database;

	$query = "SELECT * FROM #__categories WHERE section = 'com_joivideo' ";
	if ($published_only) {
	    $query .= "AND published = 1";
	}
	$query .= "ORDER BY parent_id, ordering";
	$database->setQuery($query);
	$rows = $database->loadObjectList();

	$level = 0;
	$tree = array();
	//sort by parent
	for ($i = 0, $n = count($rows); $i < $n; $i++) {
	    $row = $rows[$i];

	    $tree[$row->parent_id][] = $row;
	}

	$final = array();
	$level = 0;
	//loop through all items
	if (isset($tree[0])) {
	    for ($i = 0, $n = count($tree[0]); $i < $n; $i++) {
		$row = $tree[0][$i];
		joiGalleryCategory::recurseCategorie($tree, $final, $row, $level);
	    }

	}
	return $final;
    }
    
    function recurseCategorie($rows, & $tree, $row, $level) {

	$name = '';

	if ($level != 0) {
	    for ($i = 0; $i < $level; $i++) {
		$name .= ' - - -';
	    }
	    $name .= ' <sup>L</sup>';
	}
	$row->name = $name . ' ' . $row->name;

	$tree[] = $row;
	if (@sizeof($rows[$row->id])) {
	    for ($i = 0, $n = count($rows[$row->id]); $i < $n; $i++) {

		$child = $rows[$row->id][$i];

		joiGalleryCategory::recurseCategorie($rows, $tree, $child, $level + 1);
	    }
	}
    }
}

class joiGalleryError {
    
    function error($msg) {
	echo "<script> alert('$msg'); window.history.go(-1); </script>\n";
	exit();
    }
}

class joiGalleryPlugins extends joiPlugins {
    
    function joiGalleryPlugins($mainframe) {
	$this->joiPlugins($mainframe, 'joigallery');
    }
}